package com.youthfilmic.yuejian.weixin.core;

import com.youthfilmic.yuejian.conn.WeixinConn;
import com.youthfilmic.yuejian.dao.LoginRecordDao;
import com.youthfilmic.yuejian.dao.UserDao;
import com.youthfilmic.yuejian.domain.LoginRecord;
import com.youthfilmic.yuejian.domain.User;
import com.youthfilmic.yuejian.domain.WeixinOAuthInfo;
import com.youthfilmic.yuejian.service.UserService;
import com.youthfilmic.yuejian.util.HttpUtil;
import com.youthfilmic.yuejian.util.SaveImageFromUrlThread;
import com.youthfilmic.yuejian.util.SpringThreadPool;
import com.youthfilmic.yuejian.util.StringUtil;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Date;

/**
 * Created by youweixi on 15/10/6.
 * @ref http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html#.E7.AC.AC.E4.B8.80.E6.AD.A5.EF.BC.9A.E7.94.A8.E6.88.B7.E5.90.8C.E6.84.8F.E6.8E.88.E6.9D.83.EF.BC.8C.E8.8E.B7.E5.8F.96code
 * 这个拦截器可以实现拦截用户注册的功能，其中还会设计多线程保存用户头像的线程操作
 * @time 2015.10.6
 */
public class OAuth2Interceptor implements HandlerInterceptor {
    @Resource
    private UserDao userDao;
    @Autowired
    private UserService userService;
    @Resource
    private LoginRecordDao recordDao;


    @Override
    public boolean preHandle(HttpServletRequest request ,  HttpServletResponse response, Object handler) throws Exception{
        String uri = request.getRequestURI();
        //跳过微信支付回调通知拦截目录
        if (uri != null && uri.contains("notify.do")) return true;

        //如果用户已经登录状态，直接忽略
        Long userId = (Long)request.getSession().getAttribute("userId");
        //判断用户有没有登录
        if (userId == null){
            String code = request.getParameter("code");
            //code为空，或者code不为空，但是不是自己的code
            if(code == null || !"hehe".equals((String)request.getSession().getAttribute("myCode"))){
                //注意这里提前设置了标志位，那么如果其他用户取消登录（code没有获取到，但是已经有了标志位，那么第二次用户从其他用户的链接中进入时
                // 此时code为其他用户。session标志位也有，那么就会在第二步报错，所以第二步需要处理这种情况）
                request.getSession().setAttribute("myCode" , "hehe");
                //第一步 跳转微信授权页面获取code
                //正在准备访问的页面
                String redirectUrl = "http://yuejian.youthfilmic.com" + request.getRequestURI();
                //code为空，需要重定向进入微信授权页面
                String getCode = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+ WeixinConn.APP_ID+"&redirect_uri="+redirectUrl+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
                //访问授权页面
                //System.out.println(getCode);
                response.sendRedirect(getCode);
                return false;
                //这里需要判断一下code是不是自己的
            }else{
                //第二部 用code换取openId和access_token
                String getToken = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+WeixinConn.APP_ID+"&secret="+WeixinConn.APP_SECRET+"&code="+code+"&grant_type=authorization_code";
                JSONObject resultOpenId = HttpUtil.getJsonFromHttps(getToken, "GET", null);
                //获取信息失败
               if (resultOpenId == null){
                   PrintWriter p = response.getWriter();
                   p.print("<p>微信用户获取资料失败，请稍后再试。</p>");
                   p.flush();
                   p.close();
                   return false;
                }
                String openId = null;
                //获取code失败，但是session里面已经有了标志位
                if (!resultOpenId.containsKey("openid") || (openId = resultOpenId.getString("openid"))==null){
                    //清除标志位
                    request.getSession().removeAttribute("myCode");
                    //重入拦截器
                    response.sendRedirect("http://yuejian.youthfilmic.com" + request.getRequestURI());
                    return false;
                }
                String accessToken = resultOpenId.getString("access_token");
                String unionId = resultOpenId.getString("unionid");
                User user = userDao.findByOpenId(openId);
                if (user == null){
                    //第三步 拿着token和id去换信息
                    String getInfo = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openId+"&lang=en";
                    JSONObject userInfo = HttpUtil.getJsonFromHttps(getInfo, "GET", null);
                    String nickName = StringUtil.getTextFromEmoij(userInfo.getString("nickname") , "新用户");
                    String picUrl = userInfo.getString("headimgurl");
                    //用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
                    int sex = userInfo.getInt("sex");
                    //创建用户
                    //user = userService.createNewUser(openId ,WeixinConn.OPENID_FROM_YOUTHFILMIC_NEW_WEIXIN, unionId , nickName , picUrl , sex);
                    //保存用户信息
                    WeixinOAuthInfo info = new WeixinOAuthInfo(openId , unionId , nickName , picUrl , sex , request.getRequestURI());
                    request.getSession().setAttribute("weixinOAuthInfo", info);
                    response.sendRedirect("/bind");
                    return false;
                }

                //更新用户的unionId
                if (user != null && user.getUnionId() == null && unionId!=null && !"".equals(unionId)){
                    userDao.updateUnionIdAndOpenIdFrom(user.getId(),unionId,WeixinConn.OPENID_FROM_CURRENT);
                }

                if (user != null){
                    if (user.getPhone() == null || "".equals(user.getPhone())){
                        request.getSession().setAttribute("userIdForBind", user.getId());
                        response.sendRedirect("/bind");
                        return false;
                    }else{
                        //执行登录
                        request.getSession().setAttribute("userId" , user.getId());
                        //记录登录行为
                        LoginRecord record = new LoginRecord(user);
                        recordDao.save(record);
                        //绑定了手机
                        return true;
                    }
                }
            }
        }
        return true;
    }




    @Override
    public void afterCompletion(HttpServletRequest arg0,
                                HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {


    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                           Object arg2, ModelAndView arg3) throws Exception {


    }
}
